/**
 * 数据上传 store
 * manage all states of audit
 */
import {
  Module,
  Mutation,
  VuexModule,
  getModule,
  Action,
} from 'vuex-module-decorators'
import store from '@/store'
import {
  getDatabaseTables,
  getDataTypeImg,
  listDataLevel,
  listMaskingType,
  parseError,
  queryTableData,
  testDatabaseConnection,
  uploadDataset,
  uploadGraphDataset,
  uploadKnowledgeGraph,
  writeDataset,
  checkFileMd5,
  checkProgress,
  writeGraphDataset,
  writeKGraphDataset,
  generateMask,
  queryCurrentUserDatasetCategory,
} from '@/api/data'

import {
  // gisUploadShapeFiles,
  gisImportData,
  gisUploadShapeFiles,
  gisUploadTableFile,
  // gisUploadTableFile,
} from '@/api/gis-data'

// 数据集
export interface Dataset {
  id: number
  name: string
  type: string
}

// 数据集分类
export interface DatasetCategory {
  categoryId: number
  categoryName: string
  dataset: Array<Dataset>
}

export interface MessageModalOption {
  visible: boolean
  message: string
  tips: string
}

// 数据库链接测试状态
export enum DatabaseTestState {
  BEFORE_TEST = 'BEFORE_TEST',
  TESTING = 'TESTING',
  TEST_SUCCEED = 'TEST_SUCCEED',
  TEST_FAILED = 'TEST_FAILED',
}

@Module({ dynamic: true, namespaced: true, name: 'DataUploadStore', store })
class DataUploadStore extends VuexModule {
  /**
   * 全局
   */
  private _advancedSettingsCollapsePanelShow: boolean = false // 高级设置显示
  private _dataInformationCollapsePanelShow: boolean = false // 数据信息显示
  private _spinningMessage: string = '' // loading 文案
  private _spinning: boolean = false // loading
  public get spinningMessage() {
    return this._spinningMessage
  }
  public get spinning() {
    return this._spinning
  }
  public get advancedSettingsCollapsePanelShow() {
    return this._advancedSettingsCollapsePanelShow
  }
  public get dataInformationCollapsePanelShow() {
    return this._dataInformationCollapsePanelShow
  }
  @Mutation
  public setSpinningMessage(value: string) {
    this._spinningMessage = value
  }
  @Mutation
  public setSpinning(value: boolean) {
    this._spinning = value
  }
  @Mutation
  public setAdvancedSettingsCollapsePanelShow(value: boolean) {
    this._advancedSettingsCollapsePanelShow = value
  }
  @Mutation
  public setDataInformationCollapsePanelShow(value: boolean) {
    this._dataInformationCollapsePanelShow = value
  }

  /**
   * 数据类型
   */
  public _dataPreviewType: 'table' | 'graph' | null = null // 数据预览类型
  public get dataPreviewType() {
    return this._dataPreviewType
  }
  @Mutation
  public setDataPreviewType(type: 'table' | 'graph' | null) {
    this._dataPreviewType = type
  }

  /**
   * 基本信息
   */
  private _fileCodingType: string = 'utf-8' // 文件编码

  /**
   * 表数据
   */
  private _datasetData: any = null // 上传表后返回的数据
  private _previewedDatasetOfTable: any = null // 上传文件后的预览数据 （表数据）
  private _activeTableFileName: string | null = null // 预览 sheet
  public get datasetData() {
    return this._datasetData
  }
  public get activeTableFileName() {
    return this._activeTableFileName
  }
  @Mutation
  public setDatasetData(data: any) {
    this._datasetData = data
  }
  @Mutation
  public setActiveTableFileName(name: string) {
    this._activeTableFileName = name
  }

  // 上传数据
  private _isCancel: boolean = true // 是否取消上传

  private _dataIsUploading: boolean = false // 是否展示进度加载页面
  private _beginDatabaseUpload: boolean = false // 是否开始数据库的导入

  private _writeDatasetSucceed: boolean = false // 是否成功创建数据集
  private _messageModalOption: MessageModalOption = {
    visible: false,
    message: '',
    tips: '',
  }
  public get isCancel() {
    return this._isCancel
  }
  @Mutation
  public setIsCancel(value: boolean) {
    this._isCancel = value
  }
  public get previewedDatasetOfTable() {
    return this._previewedDatasetOfTable
  }
  @Mutation
  public setPreviewedDatasetOfTable(dataset: any) {
    this._previewedDatasetOfTable = dataset
  }
  /**
   * 上传表格型数据集
   */
  @Action
  public async uploadDatasetFile(passData: any) {
    try {
      const response = await uploadDataset({ data: passData })
      this.context.commit('setPreviewedDatasetOfTable', response.data.result)
      return response
    } catch (error) {
      throw new Error(error)
    }
  }

  public get writeDatasetSucceed() {
    return this._writeDatasetSucceed
  }
  @Mutation
  public setWriteDatasetSucceed(value: boolean) {
    this._writeDatasetSucceed = value
  }

  /**
   * 提交表格型数据集
   */
  @Action
  public async writeFinalDataset(passData: any) {
    this.context.commit('setWriteDatasetSucceed', false)
    const writeResponse = await writeDataset({ data: passData })
    if (writeResponse.data.code === 100) {
      this.context.commit('setWriteDatasetSucceed', true)
      // 在回调里获取 datastore
      // const response = await queryCurrentUserDatasetCategory()
      // this.context.commit('setDatasetCategory', response.data.result)
      // this.context.commit(
      //   'setSelectedDatasetId',
      //   writeResponse.data.result.datasetId
      // )
    }
    return writeResponse
  }
  public get messageModalOption() {
    return this._messageModalOption
  }
  @Mutation
  public setMessageModalOption(messageModalOption: MessageModalOption) {
    this._messageModalOption = messageModalOption
  }
  @Mutation
  public cancelImport() {
    this._dataIsUploading = false
    this._beginDatabaseUpload = false
    this._previewedDatasetOfTable = null
    this._writeDatasetSucceed = false

    // this._testState = DatabaseTestState.BEFORE_TEST
    // this._databaseOptions = []
    // this._databaseTables = []
    // this._databaseConfig = null
    // this._selectedTables = []
    // this._selectedTableData = null
    this._messageModalOption = { visible: false, message: '', tips: '' }
  }
  @Action
  public async parseErrorFile(passData: any) {
    const response = await parseError({ data: passData })
    return response
  }

  /**
   * 校验文件表格数据的md5值
   */
  @Action
  public async checkFileMd5(passData: any) {
    try {
      const response = await checkFileMd5({ data: passData })
      return response
    } catch (error) {
      throw new Error(error)
    }
  }

  /**
   * 获取已经上传文件块的处理进度
   */
  @Action
  public async checkProgress(passData: any) {
    try {
      return await checkProgress({ data: passData })
    } catch (error) {
      throw new Error(error)
    }
  }

  /**
   * 表数据设置导入设置脱敏设置后重新获取预览数据
   * @param postData
   */
  @Action
  public async generateMask(postData: any) {
    const response = await generateMask({ data: postData })
    return response
  }

  /**
   * 数据库导入
   */
  private _testState: DatabaseTestState = DatabaseTestState.BEFORE_TEST // 数据库链接测试状态
  private _databaseOptions: Array<string> = [] // 所有可选的数据库名
  private _databaseTables: Array<string> = [] // 所有可选的数据库表
  private _databaseConfig: any = null // 数据库的一些参数，如server,port等
  private _selectedTables: Array<string> = [] // 选中的数据表
  private _selectedTableData: any = null // 选择预览的数据库表数据
  private _databaseHeadSemantic: any = {} // 数据库导入时记录的语义，按照表名进行划分
  private _isClearForm: boolean = false // TODO why
  public get testState() {
    return this._testState
  }
  public get databaseOptions() {
    return this._databaseOptions
  }
  public get databaseTables() {
    return this._databaseTables
  }
  public get databaseConfig() {
    return this._databaseConfig
  }
  public get selectedTables() {
    return this._selectedTables
  }
  public get selectedTableData() {
    return this._selectedTableData
  }
  public get databaseHeadSemantic() {
    return this._databaseHeadSemantic
  }
  public get isClearForm() {
    return this._isClearForm
  }
  @Mutation
  public setIsClearForm(value: boolean) {
    this._isClearForm = value
  }
  @Mutation
  public setDatabaseHeadSemantic(value: any) {
    this._databaseHeadSemantic = value
  }
  @Mutation
  public setTestState(value: DatabaseTestState) {
    this._testState = value
  }
  @Mutation
  public setDatabaseOptions(options: Array<string>) {
    this._databaseOptions = options
  }
  @Mutation
  public setDatabaseTables(tables: Array<string>) {
    this._databaseTables = tables
  }
  @Mutation
  public setDatabaseConfig(config: any) {
    this._databaseConfig = config
  }
  @Mutation
  public setSelectedTables(tables: Array<string>) {
    this._selectedTables = tables
  }
  @Mutation
  public setSelectedTableData(data: any) {
    this._selectedTableData = data
  }

  /**
   * 数据库链接测试，并获取所有数据库
   */
  @Action
  public async testConnection(passData: any) {
    this.context.commit('setTestState', DatabaseTestState.TESTING)
    /** 解决await无法处理接口reject的情况 */
    try {
      const response = await testDatabaseConnection({ data: passData })
      if (response.data.code === 100) {
        this.context.commit('setTestState', DatabaseTestState.TEST_SUCCEED)
      } else {
        this.context.commit('setTestState', DatabaseTestState.TEST_FAILED)
      }
      this.context.commit('setDatabaseOptions', response.data.result)
    } catch (error) {
      console.error('testConnection error:', error)
      this.context.commit('setTestState', DatabaseTestState.TEST_FAILED)
    }
  }
  /**
   * 获取指定数据库的所有表
   */
  @Action({ commit: 'setDatabaseTables' })
  public async queryDatabaseTables(passData: any) {
    const response = await getDatabaseTables({ data: passData })
    return response.data.code === 100 ? response.data.result : []
  }
  /**
   * 获取指定数据表的数据
   */
  @Action({ commit: 'setSelectedTableData' })
  public async getTablePreviewData(passData: any) {
    try {
      const response = await queryTableData({ data: passData })
      return response.data.result
    } catch (error) {
      console.error('getTableData error', error)
      throw new Error('getTableData error')
    }
  }

  /**
   * 图数据
   */
  public _graphFileFormat: string | null = null // 图文件格式
  private _graphPreviewData: any = null // 图数据预览
  public get graphFileFormat() {
    return this._graphFileFormat
  }
  public get graphPreviewData() {
    return this._graphPreviewData
  }
  @Mutation
  public setGraphFileFormat(type: string) {
    this._graphFileFormat = type
  }
  @Mutation
  public setGraphPreviewData(data: any) {
    this._graphPreviewData = data
  }
  /**
   * 上传图数据
   */
  @Action
  public async uploadGraphFile(passData: any) {
    try {
      const response = await uploadGraphDataset({ data: passData })
      this.context.commit('setGraphPreviewData', response.data.result)
      return response
    } catch (error) {
      throw new Error(error)
    }
  }

  /**
   * 提交图数据
   */
  @Action
  public async writeGraphDataset(passData: any) {
    this.context.commit('setWriteDatasetSucceed', false)
    const writeResponse = await writeGraphDataset({ data: passData })
    if (writeResponse.data.code === 100) {
      this.context.commit('setWriteDatasetSucceed', true)
      // this.context.commit('setDatasetCategory',response.data.result)
      // this.context.commit('setSelectedDatasetId',writeResponse.data.result)
    }
    return writeResponse
  }

  /**
   * 图谱文件
   */
  private _kGraphPreviewData: any = null // 图谱文件预览
  public get kGraphPreviewData() {
    return this._kGraphPreviewData
  }

  @Mutation
  public setKGraphPreviewData(data: any) {
    this._kGraphPreviewData = data
  }
  /**
   * 上传图谱文件
   */
  @Action
  public async uploadKGraphFile(passData: any) {
    try {
      const response = await uploadKnowledgeGraph({ data: passData })
      this.context.commit('setKGraphPreviewData', response.data.result)
      return response
    } catch (error) {
      throw new Error(error)
    }
  }

  /**
   * 提交图数据
   */
  @Action
  public async writeKGraphDataset(passData: any) {
    this.context.commit('setWriteDatasetSucceed', false)
    const writeResponse = await writeKGraphDataset({ data: passData })
    if (writeResponse.data.code === 200) {
      this.context.commit('setWriteDatasetSucceed', true)
    }
    return writeResponse
  }

  /**
   * http 数据
   */
  private _httpDatasetData: any = null // http 导入执行后的数据
  public get httpDatasetData() {
    return this._httpDatasetData
  }
  @Mutation
  public setHttpDatasetData(data: any) {
    this._httpDatasetData = data
  }
  // 提交候选中对应的http表
  @Action
  public async updateHttpDataSet() {
    const response = await queryCurrentUserDatasetCategory()
    return response
  }

  /**
   * GIS 数据导入
   */
  private _previewedDatasetOfGis: any = null // gis 数据预览（表格）
  private _activeTableFileNameOfGis: string = '' // 预览激活的表
  private _uploadType: string = 'shapefile' // 上传类型
  // gis 表格型 start
  private _gisTableSetting: any = {
    tableDataGisType: 'point', // table数据导入的gis类型 'point' | 'region'
    columnGisType: 'latlng', // 字段类型 'latlng' | 'region'
    latCol: '', // 纬度字段
    lonCol: '', // 经度字段
    regionCol: '', // 行政区字段
  }

  public get previewedDatasetOfGis() {
    return this._previewedDatasetOfGis
  }
  public get uploadType() {
    return this._uploadType
  }
  public get gisTableSetting() {
    return this._gisTableSetting
  }
  public get activeTableFileNameOfGis() {
    return this._activeTableFileNameOfGis
  }

  @Mutation
  public setPreviewedDatasetOfGis(data: any) {
    this._previewedDatasetOfGis = data
  }
  @Mutation
  public setUploadType(value: string) {
    this._uploadType = value
  }
  @Mutation
  public setGisTableSetting(value: { [key: string]: string }) {
    this._gisTableSetting = {
      ...this._gisTableSetting,
      ...value,
    }
  }
  @Mutation
  public setActiveTableFileNameOfGis(value: string) {
    this._activeTableFileNameOfGis = value
  }
  /**
   * 上传 shapefile 文件
   * @param passData
   */
  @Action
  public async uploadShapeFiles(passData: any) {
    try {
      const response = await gisUploadShapeFiles({ data: passData })
      return response
    } catch (error) {
      throw new Error(error)
    }
  }
  /**
   * shapefile 确认导入
   * @param passData
   */
  @Action
  public async gisImportData(passData: any) {
    try {
      const response = await gisImportData({ data: passData })
      return response
    } catch (error) {
      throw new Error(error)
    }
  }
  /**
   * 上传表格型数据集
   * @param passData
   */
  @Action
  public async uploadTableFile(passData: any) {
    try {
      const response = await gisUploadTableFile({ data: passData })
      return response
    } catch (error) {
      throw new Error(error)
    }
  }

  /**
   * 提交表格型数据集（和表格文件上传接口相同，增加 applyType : 'gis' 参数）
   */
  @Action
  public async writeGisFinalDataset(passData: any) {
    const writeResponse = await writeDataset({ data: passData })
    return writeResponse
  }

  /**
   * 高级设置
   * @private
   */

  private _tableSeparate: string = ',' // 当前用户信息
  private _tableQuote: string = '"' // 引用符号
  private _tableEscape: string = '"' // 转义符号

  public get tableSeparate() {
    return this._tableSeparate
  }
  public get tableQuote() {
    return this._tableQuote
  }
  public get tableEscape() {
    return this._tableEscape
  }
  @Mutation
  public setTableSeparate(value: any) {
    this._tableSeparate = value
  }
  @Mutation
  public setTableQuote(value: any) {
    this._tableQuote = value
  }
  @Mutation
  public setTableEscape(value: any) {
    this._tableEscape = value
  }
  @Mutation
  public setTableSeparateQuoteEscape(valueMap: any) {
    this._tableSeparate = valueMap.tableSeparate
    this._tableQuote = valueMap.tableQuote
    this._tableEscape = valueMap.tableEscape
  }
  @Mutation
  public initSeparateQuoteEscape() {
    this._tableSeparate = ','
    this._tableQuote = '"'
    this._tableEscape = '"'
  }

  /**
   * 数据信息 - 脱敏设置
   */
  private _isDataTypeInfer: boolean = false // 是否应用推断类型
  private _isDataSemanticInfer: boolean = false // 是否应用推断语义
  private _haveSetDesensitization: any = {} // 已设置的脱敏设置  与导入设置
  private _timingSettingMaps: any = {} // 已设置的定时设置
  private _listDataLevel: any[] = [] // 脱敏类型（从后端获取）
  private _listMaskingType: any[] = [] // 脱敏方式（从后端获取）
  private _isConfigSubmit: boolean = false // 脱敏/定时配置点击提交
  public get isDataTypeInfer() {
    return this._isDataTypeInfer
  }
  public get isDataSemanticInfer() {
    return this._isDataSemanticInfer
  }
  public get haveSetDesensitization() {
    return this._haveSetDesensitization
  }
  public get timingSettingMaps() {
    return this._timingSettingMaps
  }
  @Mutation
  public setIsDataTypeInfer(value: boolean) {
    this._isDataTypeInfer = value
  }
  @Mutation
  public setIsDataSemanticInfer(value: boolean) {
    this._isDataSemanticInfer = value
  }
  @Mutation
  public setHaveSetDesensitization(value: any) {
    this._haveSetDesensitization = value
  }
  @Mutation
  public setTimingSettingMaps(value: any) {
    this._timingSettingMaps = value
  }
  @Mutation
  public setHaveSetDesensitizationContent(info: any) {
    this._haveSetDesensitization = {
      ...this._haveSetDesensitization,
      ...info,
    }
  }
  public get getListMaskingType() {
    return this._listMaskingType
  }
  @Mutation
  public setListMaskingType(type: any[]) {
    this._listMaskingType = type
  }
  /**
   * 获取所有脱敏方式
   */
  @Action({ commit: 'setListMaskingType' })
  public async queryListMaskingType() {
    const response = await listMaskingType({})
    return response.data.result
  }
  // 脱敏类型
  public get getListDataLevel() {
    return this._listDataLevel
  }
  @Mutation
  public setListDataLevel(level: any[]) {
    this._listDataLevel = level
  }
  public get isConfigSubmit() {
    return this._isConfigSubmit
  }
  /* 脱敏/定时配置提交 */
  @Mutation
  public setIsConfigSubmit(value: boolean) {
    this._isConfigSubmit = value
  }
  /**
   * 获取脱敏类型
   */
  @Action({ commit: 'setListDataLevel' })
  public async queryListDataLevel() {
    const response = await listDataLevel({})
    return response.data.result
  }

  /**
   * 初始化脱敏配置
   */
  @Mutation
  public intiHaveSetDesensitization() {
    this._isDataTypeInfer = false // 是否应用推断类型
    this._isDataSemanticInfer = false // 是否应用推断语义
    this._haveSetDesensitization = {} // 已设置的脱敏设置  与导入设置
    this._timingSettingMaps = {} // 已设置的脱敏设置  与导入设置
    // this. _listDataLevel = [] // 脱敏类型（从后端获取）
    // this. _listMaskingType = [] // 脱敏方式（从后端获取）
    this._isConfigSubmit = false // 脱敏/定时配置点击提交
  }

  // 获取图片  数据库类型图片和 json
  @Action
  public async getDatabaseTypeImg(passData: any) {
    const response = await getDataTypeImg({ data: passData })
    return response.data
  }

  /**
   * 初始化仓库
   */
  @Mutation
  public initStore() {
    this._datasetData = null // 表数据
    this._activeTableFileName = null // 查看的表
    this._advancedSettingsCollapsePanelShow = false // 高级设置
    this._haveSetDesensitization = {} // 脱敏等配置
    this._dataInformationCollapsePanelShow = false // 数据信息显示
  }
}

export default getModule(DataUploadStore)
